/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controladoresJpa;

import controladoresJpa.exceptions.NonexistentEntityException;
import controladoresJpa.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import model.DicionarioMER;
import model.Esquema;
import model.AtributoMER;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Persistence;
import model.Entidade;
import model.Relacionamento;

/**
 * Módulo MER
 * Classe de Entidade do Banco de Dados, gerada automaticamente, porém com certas modificações
 * @author Eduardo, Maylon e Kamilla
 */
public class DicionarioMERJpaController implements Serializable {

    public DicionarioMERJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;
public DicionarioMERJpaController(){
    if(emf==null)
        emf = Persistence.createEntityManagerFactory("unb-gama-threedsPU");
            }
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(DicionarioMER dicionarioMER) throws PreexistingEntityException, Exception {
        if (dicionarioMER.getAtributoMERList() == null) {
            dicionarioMER.setAtributoMERList(new ArrayList<AtributoMER>());
        }
        if (dicionarioMER.getEntidadeList() == null) {
            dicionarioMER.setEntidadeList(new ArrayList<Entidade>());
        }
        if (dicionarioMER.getRelacionamentoList() == null) {
            dicionarioMER.setRelacionamentoList(new ArrayList<Relacionamento>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Esquema nomeProjeto = dicionarioMER.getNomeEsquema();
            if (nomeProjeto != null) {
                nomeProjeto = em.getReference(nomeProjeto.getClass(), nomeProjeto.getNome());
                dicionarioMER.setNomeEsquema(nomeProjeto);
            }
            List<AtributoMER> attachedAtributoMERList = new ArrayList<AtributoMER>();
            for (AtributoMER atributoMERListAtributoMERToAttach : dicionarioMER.getAtributoMERList()) {
                atributoMERListAtributoMERToAttach = em.getReference(atributoMERListAtributoMERToAttach.getClass(), atributoMERListAtributoMERToAttach.getNome());
                attachedAtributoMERList.add(atributoMERListAtributoMERToAttach);
            }
            dicionarioMER.setAtributoMERList(attachedAtributoMERList);
            List<Entidade> attachedEntidadeList = new ArrayList<Entidade>();
            for (Entidade entidadeListEntidadeToAttach : dicionarioMER.getEntidadeList()) {
                entidadeListEntidadeToAttach = em.getReference(entidadeListEntidadeToAttach.getClass(), entidadeListEntidadeToAttach.getNome());
                attachedEntidadeList.add(entidadeListEntidadeToAttach);
            }
            dicionarioMER.setEntidadeList(attachedEntidadeList);
            List<Relacionamento> attachedRelacionamentoList = new ArrayList<Relacionamento>();
            for (Relacionamento relacionamentoListRelacionamentoToAttach : dicionarioMER.getRelacionamentoList()) {
                relacionamentoListRelacionamentoToAttach = em.getReference(relacionamentoListRelacionamentoToAttach.getClass(), relacionamentoListRelacionamentoToAttach.getNome());
                attachedRelacionamentoList.add(relacionamentoListRelacionamentoToAttach);
            }
            dicionarioMER.setRelacionamentoList(attachedRelacionamentoList);
            em.persist(dicionarioMER);
            if (nomeProjeto != null) {
                nomeProjeto.getDicionarioMERList().add(dicionarioMER);
                nomeProjeto = em.merge(nomeProjeto);
            }
            for (AtributoMER atributoMERListAtributoMER : dicionarioMER.getAtributoMERList()) {
                atributoMERListAtributoMER.getDicionarioMERList().add(dicionarioMER);
                atributoMERListAtributoMER = em.merge(atributoMERListAtributoMER);
            }
            for (Entidade entidadeListEntidade : dicionarioMER.getEntidadeList()) {
                entidadeListEntidade.getDicionarioMERList().add(dicionarioMER);
                entidadeListEntidade = em.merge(entidadeListEntidade);
            }
            for (Relacionamento relacionamentoListRelacionamento : dicionarioMER.getRelacionamentoList()) {
                relacionamentoListRelacionamento.getDicionarioMERList().add(dicionarioMER);
                relacionamentoListRelacionamento = em.merge(relacionamentoListRelacionamento);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findDicionarioMER(dicionarioMER.getId()) != null) {
                throw new PreexistingEntityException("DicionarioMER " + dicionarioMER + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(DicionarioMER dicionarioMER) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            DicionarioMER persistentDicionarioMER = em.find(DicionarioMER.class, dicionarioMER.getId());
            Esquema nomeProjetoOld = persistentDicionarioMER.getNomeEsquema();
            Esquema nomeProjetoNew = dicionarioMER.getNomeEsquema();
            List<AtributoMER> atributoMERListOld = persistentDicionarioMER.getAtributoMERList();
            List<AtributoMER> atributoMERListNew = dicionarioMER.getAtributoMERList();
            List<Entidade> entidadeListOld = persistentDicionarioMER.getEntidadeList();
            List<Entidade> entidadeListNew = dicionarioMER.getEntidadeList();
            List<Relacionamento> relacionamentoListOld = persistentDicionarioMER.getRelacionamentoList();
            List<Relacionamento> relacionamentoListNew = dicionarioMER.getRelacionamentoList();
            if (nomeProjetoNew != null) {
                nomeProjetoNew = em.getReference(nomeProjetoNew.getClass(), nomeProjetoNew.getNome());
                dicionarioMER.setNomeEsquema(nomeProjetoNew);
            }
            List<AtributoMER> attachedAtributoMERListNew = new ArrayList<AtributoMER>();
            
            if( atributoMERListNew !=null)
            for (AtributoMER atributoMERListNewAtributoMERToAttach : atributoMERListNew) {
                atributoMERListNewAtributoMERToAttach = em.getReference(atributoMERListNewAtributoMERToAttach.getClass(), atributoMERListNewAtributoMERToAttach.getNome());
                attachedAtributoMERListNew.add(atributoMERListNewAtributoMERToAttach);
            }
            atributoMERListNew = attachedAtributoMERListNew;
            dicionarioMER.setAtributoMERList(atributoMERListNew);
            List<Entidade> attachedEntidadeListNew = new ArrayList<Entidade>();
            
            if( entidadeListNew !=null)
            for (Entidade entidadeListNewEntidadeToAttach : entidadeListNew) {
                entidadeListNewEntidadeToAttach = em.getReference(entidadeListNewEntidadeToAttach.getClass(), entidadeListNewEntidadeToAttach.getNome());
                attachedEntidadeListNew.add(entidadeListNewEntidadeToAttach);
            }
            entidadeListNew = attachedEntidadeListNew;
            dicionarioMER.setEntidadeList(entidadeListNew);
            List<Relacionamento> attachedRelacionamentoListNew = new ArrayList<Relacionamento>();
            
            if( relacionamentoListNew !=null)
            for (Relacionamento relacionamentoListNewRelacionamentoToAttach : relacionamentoListNew) {
                relacionamentoListNewRelacionamentoToAttach = em.getReference(relacionamentoListNewRelacionamentoToAttach.getClass(), relacionamentoListNewRelacionamentoToAttach.getNome());
                attachedRelacionamentoListNew.add(relacionamentoListNewRelacionamentoToAttach);
            }
            relacionamentoListNew = attachedRelacionamentoListNew;
            dicionarioMER.setRelacionamentoList(relacionamentoListNew);
            dicionarioMER = em.merge(dicionarioMER);
            if (nomeProjetoOld != null && !nomeProjetoOld.equals(nomeProjetoNew)) {
                nomeProjetoOld.getDicionarioMERList().remove(dicionarioMER);
                nomeProjetoOld = em.merge(nomeProjetoOld);
            }
            if (nomeProjetoNew != null && !nomeProjetoNew.equals(nomeProjetoOld)) {
                nomeProjetoNew.getDicionarioMERList().add(dicionarioMER);
                nomeProjetoNew = em.merge(nomeProjetoNew);
            }
            
            if( atributoMERListOld !=null)
            for (AtributoMER atributoMERListOldAtributoMER : atributoMERListOld) {
                if (!atributoMERListNew.contains(atributoMERListOldAtributoMER)) {
                    atributoMERListOldAtributoMER.getDicionarioMERList().remove(dicionarioMER);
                    atributoMERListOldAtributoMER = em.merge(atributoMERListOldAtributoMER);
                }
            }
            
            if( atributoMERListNew !=null)
            for (AtributoMER atributoMERListNewAtributoMER : atributoMERListNew) {
                if (!atributoMERListOld.contains(atributoMERListNewAtributoMER)) {
                    atributoMERListNewAtributoMER.getDicionarioMERList().add(dicionarioMER);
                    atributoMERListNewAtributoMER = em.merge(atributoMERListNewAtributoMER);
                }
            }
            
            if( entidadeListOld !=null)
            for (Entidade entidadeListOldEntidade : entidadeListOld) {
                if (!entidadeListNew.contains(entidadeListOldEntidade)) {
                    entidadeListOldEntidade.getDicionarioMERList().remove(dicionarioMER);
                    entidadeListOldEntidade = em.merge(entidadeListOldEntidade);
                }
            }
            
            if( entidadeListNew !=null)
            for (Entidade entidadeListNewEntidade : entidadeListNew) {
                if (!entidadeListOld.contains(entidadeListNewEntidade)) {
                    entidadeListNewEntidade.getDicionarioMERList().add(dicionarioMER);
                    entidadeListNewEntidade = em.merge(entidadeListNewEntidade);
                }
            }
            
            if(relacionamentoListOld  !=null)
            for (Relacionamento relacionamentoListOldRelacionamento : relacionamentoListOld) {
                if (!relacionamentoListNew.contains(relacionamentoListOldRelacionamento)) {
                    relacionamentoListOldRelacionamento.getDicionarioMERList().remove(dicionarioMER);
                    relacionamentoListOldRelacionamento = em.merge(relacionamentoListOldRelacionamento);
                }
            }
            
            if( relacionamentoListNew !=null)
            for (Relacionamento relacionamentoListNewRelacionamento : relacionamentoListNew) {
                if (!relacionamentoListOld.contains(relacionamentoListNewRelacionamento)) {
                    relacionamentoListNewRelacionamento.getDicionarioMERList().add(dicionarioMER);
                    relacionamentoListNewRelacionamento = em.merge(relacionamentoListNewRelacionamento);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = dicionarioMER.getId();
                if (findDicionarioMER(id) == null) {
                    throw new NonexistentEntityException("The dicionarioMER with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            DicionarioMER dicionarioMER;
            try {
                dicionarioMER = em.getReference(DicionarioMER.class, id);
                dicionarioMER.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The dicionarioMER with id " + id + " no longer exists.", enfe);
            }
            Esquema nomeProjeto = dicionarioMER.getNomeEsquema();
            if (nomeProjeto != null) {
                nomeProjeto.getDicionarioMERList().remove(dicionarioMER);
                nomeProjeto = em.merge(nomeProjeto);
            }
            List<AtributoMER> atributoMERList = dicionarioMER.getAtributoMERList();
            for (AtributoMER atributoMERListAtributoMER : atributoMERList) {
                atributoMERListAtributoMER.getDicionarioMERList().remove(dicionarioMER);
                atributoMERListAtributoMER = em.merge(atributoMERListAtributoMER);
            }
            List<Entidade> entidadeList = dicionarioMER.getEntidadeList();
            for (Entidade entidadeListEntidade : entidadeList) {
                entidadeListEntidade.getDicionarioMERList().remove(dicionarioMER);
                entidadeListEntidade = em.merge(entidadeListEntidade);
            }
            List<Relacionamento> relacionamentoList = dicionarioMER.getRelacionamentoList();
            for (Relacionamento relacionamentoListRelacionamento : relacionamentoList) {
                relacionamentoListRelacionamento.getDicionarioMERList().remove(dicionarioMER);
                relacionamentoListRelacionamento = em.merge(relacionamentoListRelacionamento);
            }
            em.remove(dicionarioMER);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<DicionarioMER> findDicionarioMEREntities() {
        return findDicionarioMEREntities(true, -1, -1);
    }

    public List<DicionarioMER> findDicionarioMEREntities(int maxResults, int firstResult) {
        return findDicionarioMEREntities(false, maxResults, firstResult);
    }

    private List<DicionarioMER> findDicionarioMEREntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(DicionarioMER.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public DicionarioMER findDicionarioMER(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(DicionarioMER.class, id);
        } finally {
            em.close();
        }
    }

    public int getDicionarioMERCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<DicionarioMER> rt = cq.from(DicionarioMER.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
